// Copyright (C)2012 Johann Duscher. All rights reserved.
//
// This file is part of QwTAPI.
//
// QwTAPI is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// QwTAPI is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with QwTAPI.  If not, see <http://www.gnu.org/licenses/>.

#pragma once

#include <QtCore/qglobal.h>

#ifdef QWTAPI_LIB
# define QWTAPI_EXPORT Q_DECL_EXPORT
#else
# define QWTAPI_EXPORT Q_DECL_IMPORT
#endif

#define TAPI_VERSION_1_3 (0x00010003)     // First released version of TAPI (Win3.1)
#define TAPI_VERSION_1_4 (0x00010004)     // Latest 16-bit version (Chicago)
#define TAPI_VERSION_2_0 (0x00020000)     // Initial 32-bit version (NT)
#define TAPI_VERSION_2_1 (0x00020001)     // NT/Win98
#define TAPI_VERSION_2_2 (0x00020002)     // SP2
#define TAPI_VERSION_3_0 (0x00030000)     // Win2K
#define TAPI_VERSION_3_1 (0x00030001)     // WinXP

#define TAPI_CURRENT_VERSION TAPI_VERSION_2_0

#include <qt_windows.h>
#include <tapi.h>

#include <QDebug>
#include <QObject>
#include <QString>
#include <QFlag>
#include <QMetaObject>
#include <QMetaEnum>
#include <QByteArray>
#include <QList>
#include <QMap>
#include <QMutex>
#include <QMutexLocker>
#include <QScopedPointer>
#include <QScopedArrayPointer>
#include <QTimer>


#if defined Q_CC_MSVC && _MSC_VER < 1300
# define QWTAPI_DECLARE_INCOMPATIBLE_FLAGS(Flags)
#else
# define QWTAPI_DECLARE_INCOMPATIBLE_FLAGS(Flags) \
    QWTAPI_EXPORT inline QIncompatibleFlag operator|(Flags::enum_type f1, int f2) { return QIncompatibleFlag(int(f1) | f2); }
#endif

#define QWTAPI_DECLARE_OPERATORS_FOR_FLAGS(Flags) \
    QWTAPI_EXPORT inline QFlags<Flags::enum_type> operator|(Flags::enum_type f1, Flags::enum_type f2) { return QFlags<Flags::enum_type>(f1) | f2; } \
    QWTAPI_EXPORT inline QFlags<Flags::enum_type> operator|(Flags::enum_type f1, QFlags<Flags::enum_type> f2) { return f2 | f1; } \
    QWTAPI_DECLARE_INCOMPATIBLE_FLAGS(Flags)

#define QWTAPI_DECLARE_FLAG_OPERATORS(EnumType) \
    QWTAPI_DECLARE_OPERATORS_FOR_FLAGS(EnumType::Constants) \
    QWTAPI_EXPORT inline QDebug operator<<(QDebug dbg, EnumType::Constants f) { dbg.nospace() << (QString::number(f) + "=" + toString<EnumType>(f)); return dbg.space(); }

#define QWTAPI_DECLARE_ENUM_OPERATORS(EnumType) \
    QWTAPI_EXPORT inline QDebug operator<<(QDebug dbg, EnumType::Constant c) { dbg.nospace() << (QString::number(c) + "=" + toString<EnumType>(c)); return dbg.space(); }


Q_DECLARE_METATYPE(DWORD)

namespace qwtapi
{

template <typename E>
QWTAPI_EXPORT inline QString toString(typename E::Constant value)
{
    Q_ASSERT(0 == E::staticMetaObject.indexOfEnumerator("Constant"));
    Q_ASSERT(!E::staticMetaObject.enumerator(0).isFlag());
    return E::staticMetaObject.enumerator(0).valueToKey(value);
}

template <typename E>
QWTAPI_EXPORT inline typename E::Constant fromString(const char* key)
{
    Q_ASSERT(0 == E::staticMetaObject.indexOfEnumerator("Constant"));
    Q_ASSERT(!E::staticMetaObject.enumerator(0).isFlag());
    return E::staticMetaObject.enumerator(0).keyToValue(key);
}

template <typename E>
QWTAPI_EXPORT inline QByteArray toString(typename E::Constants value)
{
    Q_ASSERT(0 == E::staticMetaObject.indexOfEnumerator("Constant"));
    Q_ASSERT(!E::staticMetaObject.enumerator(0).isFlag());
    Q_ASSERT(1 == E::staticMetaObject.indexOfEnumerator("Constants"));
    Q_ASSERT(E::staticMetaObject.enumerator(1).isFlag());
    return E::staticMetaObject.enumerator(1).valueToKeys(value);
}

template <typename E>
QWTAPI_EXPORT inline typename E::Constants fromString(const char* key)
{
    Q_ASSERT(0 == E::staticMetaObject.indexOfEnumerator("Constant"));
    Q_ASSERT(!E::staticMetaObject.enumerator(0).isFlag());
    Q_ASSERT(1 == E::staticMetaObject.indexOfEnumerator("Constants"));
    Q_ASSERT(E::staticMetaObject.enumerator(1).isFlag());
    return E::staticMetaObject.enumerator(1).keysToValue(key);
}

class QWTAPI_EXPORT Message
{
    Q_GADGET
    Q_ENUMS(Constant)

public:
    enum Constant
    {
        ADDRESSSTATE = LINE_ADDRESSSTATE,
        APPNEWCALL = LINE_APPNEWCALL,
        //APPNEWCALLHUB = LINE_APPNEWCALLHUB,
        CALLINFO = LINE_CALLINFO,
        //CALLHUBCLOSE = LINE_CALLHUBCLOSE,
        CALLSTATE = LINE_CALLSTATE,
        CLOSE = LINE_CLOSE,
        CREATE = LINE_CREATE,
        DEVSPECIFIC = LINE_DEVSPECIFIC,
        //DEVSPECIFICEX = LINE_DEVSPECIFICEX,
        DEVSPECIFICFEATURE = LINE_DEVSPECIFICFEATURE,
        GATHERDIGITS = LINE_GATHERDIGITS,
        GENERATE = LINE_GENERATE,
        LINEDEVSTATE = LINE_LINEDEVSTATE,
        MONITORDIGITS = LINE_MONITORDIGITS,
        MONITORMEDIA = LINE_MONITORMEDIA,
        MONITORTONE = LINE_MONITORTONE,
        REMOVE = LINE_REMOVE,
        REPLY = LINE_REPLY,
        REQUEST = LINE_REQUEST,
    };
};
QWTAPI_DECLARE_ENUM_OPERATORS(Message)

class QWTAPI_EXPORT AddressState
{
    Q_GADGET
    Q_ENUMS(Constant)
    Q_FLAGS(Constants)

public:
    enum Constant
    {
        CAPSCHANGE = LINEADDRESSSTATE_CAPSCHANGE,
        DEVSPECIFIC = LINEADDRESSSTATE_DEVSPECIFIC,
        FORWARD = LINEADDRESSSTATE_FORWARD,
        INUSEMANY = LINEADDRESSSTATE_INUSEMANY,
        INUSEONE = LINEADDRESSSTATE_INUSEONE,
        INUSEZERO = LINEADDRESSSTATE_INUSEZERO,
        NUMCALLS = LINEADDRESSSTATE_NUMCALLS,
        OTHER = LINEADDRESSSTATE_OTHER,
        TERMINALS = LINEADDRESSSTATE_TERMINALS,
    };
    Q_DECLARE_FLAGS(Constants, Constant);
};
QWTAPI_DECLARE_ENUM_OPERATORS(AddressState)
QWTAPI_DECLARE_FLAG_OPERATORS(AddressState)

class QWTAPI_EXPORT CallPrivilege
{
    Q_GADGET
    Q_ENUMS(Constant)
    Q_FLAGS(Constants)

public:
    enum Constant
    {
        OWNER = LINECALLPRIVILEGE_OWNER,
        MONITOR = LINECALLPRIVILEGE_MONITOR,
        NONE = LINECALLPRIVILEGE_NONE,
    };
    Q_DECLARE_FLAGS(Constants, Constant);
};
QWTAPI_DECLARE_ENUM_OPERATORS(CallPrivilege)
QWTAPI_DECLARE_FLAG_OPERATORS(CallPrivilege)

class QWTAPI_EXPORT CallState
{
    Q_GADGET
    Q_ENUMS(Constant)

public:
    enum Constant
    {
        IDLE = LINECALLSTATE_IDLE,
        OFFERING = LINECALLSTATE_OFFERING,
        ACCEPTED = LINECALLSTATE_ACCEPTED,
        DIALTONE = LINECALLSTATE_DIALTONE,
        DIALING = LINECALLSTATE_DIALING,
        RINGBACK = LINECALLSTATE_RINGBACK,
        BUSY = LINECALLSTATE_BUSY,
        SPECIALINFO = LINECALLSTATE_SPECIALINFO,
        CONNECTED = LINECALLSTATE_CONNECTED,
        PROCEEDING = LINECALLSTATE_PROCEEDING,
        ONHOLD = LINECALLSTATE_ONHOLD,
        CONFERENCED = LINECALLSTATE_CONFERENCED,
        ONHOLDPENDCONF = LINECALLSTATE_ONHOLDPENDCONF,
        ONHOLDPENDTRANSFER = LINECALLSTATE_ONHOLDPENDTRANSFER,
        DISCONNECTED = LINECALLSTATE_DISCONNECTED,
        UNKNOWN = LINECALLSTATE_UNKNOWN,
    };
};
QWTAPI_DECLARE_ENUM_OPERATORS(CallState)

class QWTAPI_EXPORT CallInfoState
{
    Q_GADGET
    Q_ENUMS(Constant)
    Q_FLAGS(Constants)

public:
    enum Constant
    {
        APPSPECIFIC = LINECALLINFOSTATE_APPSPECIFIC,
        BEARERMODE = LINECALLINFOSTATE_BEARERMODE,
        CALLDATA = LINECALLINFOSTATE_CALLDATA,
        CALLEDID = LINECALLINFOSTATE_CALLEDID,
        CALLERID = LINECALLINFOSTATE_CALLERID,
        CALLID = LINECALLINFOSTATE_CALLID,
        CHARGINGINFO = LINECALLINFOSTATE_CHARGINGINFO,
        COMPLETIONID = LINECALLINFOSTATE_COMPLETIONID,
        CONNECTEDID = LINECALLINFOSTATE_CONNECTEDID,
        DEVSPECIFIC = LINECALLINFOSTATE_DEVSPECIFIC,
        DIALPARAMS = LINECALLINFOSTATE_DIALPARAMS,
        DISPLAY = LINECALLINFOSTATE_DISPLAY,
        HIGHLEVELCOMP = LINECALLINFOSTATE_HIGHLEVELCOMP,
        LOWLEVELCOMP = LINECALLINFOSTATE_LOWLEVELCOMP,
        MEDIAMODE = LINECALLINFOSTATE_MEDIAMODE,
        MONITORMODES = LINECALLINFOSTATE_MONITORMODES,
        NUMMONITORS = LINECALLINFOSTATE_NUMMONITORS,
        NUMOWNERDECR = LINECALLINFOSTATE_NUMOWNERDECR,
        NUMOWNERINCR = LINECALLINFOSTATE_NUMOWNERINCR,
        ORIGIN = LINECALLINFOSTATE_ORIGIN,
        OTHER = LINECALLINFOSTATE_OTHER,
        QOS = LINECALLINFOSTATE_QOS,
        RATE = LINECALLINFOSTATE_RATE,
        REASON = LINECALLINFOSTATE_REASON,
        REDIRECTINGID = LINECALLINFOSTATE_REDIRECTINGID,
        REDIRECTIONID = LINECALLINFOSTATE_REDIRECTIONID,
        RELATEDCALLID = LINECALLINFOSTATE_RELATEDCALLID,
        TERMINAL = LINECALLINFOSTATE_TERMINAL,
        TREATMENT = LINECALLINFOSTATE_TREATMENT,
        TRUNK = LINECALLINFOSTATE_TRUNK,
        USERUSERINFO = LINECALLINFOSTATE_USERUSERINFO,
    };
    Q_DECLARE_FLAGS(Constants, Constant);
};
QWTAPI_DECLARE_ENUM_OPERATORS(CallInfoState)
QWTAPI_DECLARE_FLAG_OPERATORS(CallInfoState)

class QWTAPI_EXPORT BusyMode
{
    Q_GADGET
    Q_ENUMS(Constant)
    Q_FLAGS(Constants)

public:
    enum Constant
    {
        STATION = LINEBUSYMODE_STATION,
        TRUNK = LINEBUSYMODE_TRUNK,
        UNKNOWN = LINEBUSYMODE_UNKNOWN,
        UNAVAIL = LINEBUSYMODE_UNAVAIL,
    };
    Q_DECLARE_FLAGS(Constants, Constant);
};
QWTAPI_DECLARE_ENUM_OPERATORS(BusyMode)
QWTAPI_DECLARE_FLAG_OPERATORS(BusyMode)

class QWTAPI_EXPORT ConnectedMode
{
    Q_GADGET
    Q_ENUMS(Constant)
    Q_FLAGS(Constants)

public:
    enum Constant
    {
        ACTIVE = LINECONNECTEDMODE_ACTIVE,
        ACTIVEHELD = LINECONNECTEDMODE_ACTIVEHELD,
        CONFIRMED = LINECONNECTEDMODE_CONFIRMED,
        INACTIVE = LINECONNECTEDMODE_INACTIVE,
        INACTIVEHELD = LINECONNECTEDMODE_INACTIVEHELD,
    };
    Q_DECLARE_FLAGS(Constants, Constant);
};
QWTAPI_DECLARE_ENUM_OPERATORS(ConnectedMode)
QWTAPI_DECLARE_FLAG_OPERATORS(ConnectedMode)

class QWTAPI_EXPORT DialtoneMode
{
    Q_GADGET
    Q_ENUMS(Constant)
    Q_FLAGS(Constants)

public:
    enum Constant
    {
        EXTERNAL = LINEDIALTONEMODE_EXTERNAL,
        INTERNAL = LINEDIALTONEMODE_INTERNAL,
        NORMAL = LINEDIALTONEMODE_NORMAL,
        SPECIAL = LINEDIALTONEMODE_SPECIAL,
        UNAVAIL = LINEDIALTONEMODE_UNAVAIL,
        UNKNOWN = LINEDIALTONEMODE_UNKNOWN,
    };
    Q_DECLARE_FLAGS(Constants, Constant);
};
QWTAPI_DECLARE_ENUM_OPERATORS(DialtoneMode)
QWTAPI_DECLARE_FLAG_OPERATORS(DialtoneMode)

class QWTAPI_EXPORT OfferingMode
{
    Q_GADGET
    Q_ENUMS(Constant)
    Q_FLAGS(Constants)

public:
    enum Constant
    {
        ACTIVE = LINEOFFERINGMODE_ACTIVE,
        INACTIVE = LINEOFFERINGMODE_INACTIVE,
    };
    Q_DECLARE_FLAGS(Constants, Constant);
};
QWTAPI_DECLARE_ENUM_OPERATORS(OfferingMode)
QWTAPI_DECLARE_FLAG_OPERATORS(OfferingMode)

class QWTAPI_EXPORT SpecialInfo
{
    Q_GADGET
    Q_ENUMS(Constant)
    Q_FLAGS(Constants)

public:
    enum Constant
    {
        CUSTIRREG = LINESPECIALINFO_CUSTIRREG,
        NOCIRCUIT = LINESPECIALINFO_NOCIRCUIT,
        REORDER = LINESPECIALINFO_REORDER,
        UNAVAIL = LINESPECIALINFO_UNAVAIL,
        UNKNOWN = LINESPECIALINFO_UNKNOWN,
    };
    Q_DECLARE_FLAGS(Constants, Constant);
};
QWTAPI_DECLARE_ENUM_OPERATORS(SpecialInfo)
QWTAPI_DECLARE_FLAG_OPERATORS(SpecialInfo)

class QWTAPI_EXPORT DisconnectMode
{
    Q_GADGET
    Q_ENUMS(Constant)
    Q_FLAGS(Constants)

public:
    enum Constant
    {
        BADADDRESS = LINEDISCONNECTMODE_BADADDRESS,
        BLOCKED = LINEDISCONNECTMODE_BLOCKED,
        BUSY = LINEDISCONNECTMODE_BUSY,
        CANCELLED = LINEDISCONNECTMODE_CANCELLED,
        CONGESTION = LINEDISCONNECTMODE_CONGESTION,
        DONOTDISTURB = LINEDISCONNECTMODE_DONOTDISTURB,
        FORWARDED = LINEDISCONNECTMODE_FORWARDED,
        INCOMPATIBLE = LINEDISCONNECTMODE_INCOMPATIBLE,
        NOANSWER = LINEDISCONNECTMODE_NOANSWER,
        NODIALTONE = LINEDISCONNECTMODE_NODIALTONE,
        NORMAL = LINEDISCONNECTMODE_NORMAL,
        NUMBERCHANGED = LINEDISCONNECTMODE_NUMBERCHANGED,
        OUTOFORDER = LINEDISCONNECTMODE_OUTOFORDER,
        PICKUP = LINEDISCONNECTMODE_PICKUP,
        QOSUNAVAIL = LINEDISCONNECTMODE_QOSUNAVAIL,
        REJECT = LINEDISCONNECTMODE_REJECT,
        TEMPFAILURE = LINEDISCONNECTMODE_TEMPFAILURE,
        UNAVAIL = LINEDISCONNECTMODE_UNAVAIL,
        UNKNOWN = LINEDISCONNECTMODE_UNKNOWN,
        UNREACHABLE = LINEDISCONNECTMODE_UNREACHABLE,
    };
    Q_DECLARE_FLAGS(Constants, Constant);
};
QWTAPI_DECLARE_ENUM_OPERATORS(DisconnectMode)
QWTAPI_DECLARE_FLAG_OPERATORS(DisconnectMode)

class QWTAPI_EXPORT GatherTerm
{
    Q_GADGET
    Q_ENUMS(Constant)

public:
    enum Constant
    {
        BUFFERFULL = LINEGATHERTERM_BUFFERFULL,
        CANCEL = LINEGATHERTERM_CANCEL,
        FIRSTTIMEOUT = LINEGATHERTERM_FIRSTTIMEOUT,
        INTERTIMEOUT = LINEGATHERTERM_INTERTIMEOUT,
        TERMDIGIT = LINEGATHERTERM_TERMDIGIT,
    };
};
QWTAPI_DECLARE_ENUM_OPERATORS(GatherTerm)

class QWTAPI_EXPORT GenerateTerm
{
    Q_GADGET
    Q_ENUMS(Constant)

public:
    enum Constant
    {
        CANCEL = LINEGENERATETERM_CANCEL,
        DONE = LINEGENERATETERM_DONE,
    };
};
QWTAPI_DECLARE_ENUM_OPERATORS(GenerateTerm)

class QWTAPI_EXPORT LineDevState
{
    Q_GADGET
    Q_ENUMS(Constant)
    Q_FLAGS(Constants)

public:
    enum Constant
    {
        BATTERY = LINEDEVSTATE_BATTERY,
        CAPSCHANGE = LINEDEVSTATE_CAPSCHANGE,
        CLOSE = LINEDEVSTATE_CLOSE,
        CONFIGCHANGE = LINEDEVSTATE_CONFIGCHANGE,
        COMPLCANCEL = LINEDEVSTATE_COMPLCANCEL,
        CONNECTED = LINEDEVSTATE_CONNECTED,
        DEVSPECIFIC = LINEDEVSTATE_DEVSPECIFIC,
        DISCONNECTED = LINEDEVSTATE_DISCONNECTED,
        INSERVICE = LINEDEVSTATE_INSERVICE,
        LOCK = LINEDEVSTATE_LOCK,
        MAINTENANCE = LINEDEVSTATE_MAINTENANCE,
        MSGWAITOFF = LINEDEVSTATE_MSGWAITOFF,
        MSGWAITON = LINEDEVSTATE_MSGWAITON,
        NUMCALLS = LINEDEVSTATE_NUMCALLS,
        NUMCOMPLETIONS = LINEDEVSTATE_NUMCOMPLETIONS,
        OPEN = LINEDEVSTATE_OPEN,
        OTHER = LINEDEVSTATE_OTHER,
        OUTOFSERVICE = LINEDEVSTATE_OUTOFSERVICE,
        REINIT = LINEDEVSTATE_REINIT,
        REMOVED = LINEDEVSTATE_REMOVED,
        RINGING = LINEDEVSTATE_RINGING,
        ROAMMODE = LINEDEVSTATE_ROAMMODE,
        SIGNAL = LINEDEVSTATE_SIGNAL,
        TERMINALS = LINEDEVSTATE_TERMINALS,
        TRANSLATECHANGE = LINEDEVSTATE_TRANSLATECHANGE,
    };
    Q_DECLARE_FLAGS(Constants, Constant);
};
QWTAPI_DECLARE_ENUM_OPERATORS(LineDevState)
QWTAPI_DECLARE_FLAG_OPERATORS(LineDevState)

class QWTAPI_EXPORT DigitMode
{
    Q_GADGET
    Q_ENUMS(Constant)

public:
    enum Constant
    {
        DTMF = LINEDIGITMODE_DTMF,
        DTMFEND = LINEDIGITMODE_DTMFEND,
        PULSE = LINEDIGITMODE_PULSE,
    };
};
QWTAPI_DECLARE_ENUM_OPERATORS(DigitMode)

class QWTAPI_EXPORT MediaMode
{
    Q_GADGET
    Q_ENUMS(Constant)
    Q_FLAGS(Constants)

public:
    enum Constant
    {
        AUTOMATEDVOICE = LINEMEDIAMODE_AUTOMATEDVOICE,
        DATAMODEM = LINEMEDIAMODE_DATAMODEM,
        ADSI = LINEMEDIAMODE_ADSI,
        DIGITALDATA = LINEMEDIAMODE_DIGITALDATA,
        G3FAX = LINEMEDIAMODE_G3FAX,
        G4FAX = LINEMEDIAMODE_G4FAX,
        INTERACTIVEVOICE = LINEMEDIAMODE_INTERACTIVEVOICE,
        MIXED = LINEMEDIAMODE_MIXED,
        TDD = LINEMEDIAMODE_TDD,
        TELETEX = LINEMEDIAMODE_TELETEX,
        TELEX = LINEMEDIAMODE_TELEX,
        //VIDEO = LINEMEDIAMODE_VIDEO,
        VIDEOTEX = LINEMEDIAMODE_VIDEOTEX,
        VOICEVIEW = LINEMEDIAMODE_VOICEVIEW,
        UNKNOWN = LINEMEDIAMODE_UNKNOWN,
    };
    Q_DECLARE_FLAGS(Constants, Constant);
};
QWTAPI_DECLARE_ENUM_OPERATORS(MediaMode)
QWTAPI_DECLARE_FLAG_OPERATORS(MediaMode)

class QWTAPI_EXPORT RequestMode
{
    Q_GADGET
    Q_ENUMS(Constant)

public:
    enum Constant
    {
        DROP = LINEREQUESTMODE_DROP,
        MAKECALL = LINEREQUESTMODE_MAKECALL,
        // MEDIACALL = LINEREQUESTMODE_MEDIACALL, (constant is obsolete)
    };
};
QWTAPI_DECLARE_ENUM_OPERATORS(RequestMode)

class QWTAPI_EXPORT StringFormat
{
    Q_GADGET
    Q_ENUMS(Constant)

public:
    enum Constant
    {
        ASCII = STRINGFORMAT_ASCII,
        BINARY = STRINGFORMAT_BINARY,
        DBCS = STRINGFORMAT_DBCS,
        UNIC = STRINGFORMAT_UNICODE,
    };
};
QWTAPI_DECLARE_ENUM_OPERATORS(StringFormat)

class QWTAPI_EXPORT Error
{
    Q_GADGET
    Q_ENUMS(Constant)

public:
    enum Constant
    {
        ALLOCATED = LINEERR_ALLOCATED,
        BADDEVICEID = LINEERR_BADDEVICEID,
        BEARERMODEUNAVAIL = LINEERR_BEARERMODEUNAVAIL,
        CALLUNAVAIL = LINEERR_CALLUNAVAIL,
        COMPLETIONOVERRUN = LINEERR_COMPLETIONOVERRUN,
        CONFERENCEFULL = LINEERR_CONFERENCEFULL,
        DIALBILLING = LINEERR_DIALBILLING,
        DIALDIALTONE = LINEERR_DIALDIALTONE,
        DIALPROMPT = LINEERR_DIALPROMPT,
        DIALQUIET = LINEERR_DIALQUIET,
        INCOMPATIBLEAPIVERSION = LINEERR_INCOMPATIBLEAPIVERSION,
        INCOMPATIBLEEXTVERSION = LINEERR_INCOMPATIBLEEXTVERSION,
        INIFILECORRUPT = LINEERR_INIFILECORRUPT,
        INUSE = LINEERR_INUSE,
        INVALADDRESS = LINEERR_INVALADDRESS,
        INVALADDRESSID = LINEERR_INVALADDRESSID,
        INVALADDRESSMODE = LINEERR_INVALADDRESSMODE,
        INVALADDRESSSTATE = LINEERR_INVALADDRESSSTATE,
        INVALAPPHANDLE = LINEERR_INVALAPPHANDLE,
        INVALAPPNAME = LINEERR_INVALAPPNAME,
        INVALBEARERMODE = LINEERR_INVALBEARERMODE,
        INVALCALLCOMPLMODE = LINEERR_INVALCALLCOMPLMODE,
        INVALCALLHANDLE = LINEERR_INVALCALLHANDLE,
        INVALCALLPARAMS = LINEERR_INVALCALLPARAMS,
        INVALCALLPRIVILEGE = LINEERR_INVALCALLPRIVILEGE,
        INVALCALLSELECT = LINEERR_INVALCALLSELECT,
        INVALCALLSTATE = LINEERR_INVALCALLSTATE,
        INVALCALLSTATELIST = LINEERR_INVALCALLSTATELIST,
        INVALCARD = LINEERR_INVALCARD,
        INVALCOMPLETIONID = LINEERR_INVALCOMPLETIONID,
        INVALCONFCALLHANDLE = LINEERR_INVALCONFCALLHANDLE,
        INVALCONSULTCALLHANDLE = LINEERR_INVALCONSULTCALLHANDLE,
        INVALCOUNTRYCODE = LINEERR_INVALCOUNTRYCODE,
        INVALDEVICECLASS = LINEERR_INVALDEVICECLASS,
        INVALDEVICEHANDLE = LINEERR_INVALDEVICEHANDLE,
        INVALDIALPARAMS = LINEERR_INVALDIALPARAMS,
        INVALDIGITLIST = LINEERR_INVALDIGITLIST,
        INVALDIGITMODE = LINEERR_INVALDIGITMODE,
        INVALDIGITS = LINEERR_INVALDIGITS,
        INVALEXTVERSION = LINEERR_INVALEXTVERSION,
        INVALGROUPID = LINEERR_INVALGROUPID,
        INVALLINEHANDLE = LINEERR_INVALLINEHANDLE,
        INVALLINESTATE = LINEERR_INVALLINESTATE,
        INVALLOCATION = LINEERR_INVALLOCATION,
        INVALMEDIALIST = LINEERR_INVALMEDIALIST,
        INVALMEDIAMODE = LINEERR_INVALMEDIAMODE,
        INVALMESSAGEID = LINEERR_INVALMESSAGEID,
        INVALPARAM = LINEERR_INVALPARAM,
        INVALPARKID = LINEERR_INVALPARKID,
        INVALPARKMODE = LINEERR_INVALPARKMODE,
        INVALPOINTER = LINEERR_INVALPOINTER,
        INVALPRIVSELECT = LINEERR_INVALPRIVSELECT,
        INVALRATE = LINEERR_INVALRATE,
        INVALREQUESTMODE = LINEERR_INVALREQUESTMODE,
        INVALTERMINALID = LINEERR_INVALTERMINALID,
        INVALTERMINALMODE = LINEERR_INVALTERMINALMODE,
        INVALTIMEOUT = LINEERR_INVALTIMEOUT,
        INVALTONE = LINEERR_INVALTONE,
        INVALTONELIST = LINEERR_INVALTONELIST,
        INVALTONEMODE = LINEERR_INVALTONEMODE,
        INVALTRANSFERMODE = LINEERR_INVALTRANSFERMODE,
        LINEMAPPERFAILED = LINEERR_LINEMAPPERFAILED,
        NOCONFERENCE = LINEERR_NOCONFERENCE,
        NODEVICE = LINEERR_NODEVICE,
        NODRIVER = LINEERR_NODRIVER,
        NOMEM = LINEERR_NOMEM,
        NOREQUEST = LINEERR_NOREQUEST,
        NOTOWNER = LINEERR_NOTOWNER,
        NOTREGISTERED = LINEERR_NOTREGISTERED,
        OPERATIONFAILED = LINEERR_OPERATIONFAILED,
        OPERATIONUNAVAIL = LINEERR_OPERATIONUNAVAIL,
        RATEUNAVAIL = LINEERR_RATEUNAVAIL,
        RESOURCEUNAVAIL = LINEERR_RESOURCEUNAVAIL,
        REQUESTOVERRUN = LINEERR_REQUESTOVERRUN,
        STRUCTURETOOSMALL = LINEERR_STRUCTURETOOSMALL,
        TARGETNOTFOUND = LINEERR_TARGETNOTFOUND,
        TARGETSELF = LINEERR_TARGETSELF,
        UNINITIALIZED = LINEERR_UNINITIALIZED,
        USERUSERINFOTOOBIG = LINEERR_USERUSERINFOTOOBIG,
        REINIT = LINEERR_REINIT,
        ADDRESSBLOCKED = LINEERR_ADDRESSBLOCKED,
        BILLINGREJECTED = LINEERR_BILLINGREJECTED,
        INVALFEATURE = LINEERR_INVALFEATURE,
        NOMULTIPLEINSTANCE = LINEERR_NOMULTIPLEINSTANCE,
#if (TAPI_CURRENT_VERSION >= TAPI_VERSION_2_0)
        INVALAGENTID = LINEERR_INVALAGENTID,
        INVALAGENTGROUP = LINEERR_INVALAGENTGROUP,
        INVALPASSWORD = LINEERR_INVALPASSWORD,
        INVALAGENTSTATE = LINEERR_INVALAGENTSTATE,
        INVALAGENTACTIVITY = LINEERR_INVALAGENTACTIVITY,
        DIALVOICEDETECT = LINEERR_DIALVOICEDETECT,
#endif
#if (TAPI_CURRENT_VERSION >= TAPI_VERSION_2_2)
        USERCANCELLED = LINEERR_USERCANCELLED,
#endif
#if (TAPI_CURRENT_VERSION >= TAPI_VERSION_3_0)
        INVALADDRESSTYPE = LINEERR_INVALADDRESSTYPE,
#endif
#if (TAPI_CURRENT_VERSION >= TAPI_VERSION_2_2)
        INVALAGENTSESSIONSTATE = LINEERR_INVALAGENTSESSIONSTATE,
        DISCONNECTED = LINEERR_DISCONNECTED,
        SERVICE_NOT_RUNNING = LINEERR_SERVICE_NOT_RUNNING,
#endif
    };

    inline static bool isKnown(LONG value)
    {
        return 0 != staticMetaObject.enumerator(0).valueToKey(value);
    }
};
QWTAPI_DECLARE_ENUM_OPERATORS(Error)

QWTAPI_EXPORT inline QString toString(LONG result)
{
    return Error::isKnown(result) ? toString<Error>(static_cast<Error::Constant>(result)) : QString("%1").arg(result, 8, 16, QChar('0'));
}

QWTAPI_EXPORT inline void registerMetaTypes()
{
    qRegisterMetaType<DWORD>("DWORD");
    qRegisterMetaType<qwtapi::Message::Constant>("qwtapi::Message::Constant");
}

}
